package com.codeplatform.mapper;

import com.codeplatform.entity.CodeRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 代码记录数据访问接口
 * 
 * @author CodePlatform
 * @since 2024-01-01
 */
@Mapper
public interface CodeRecordMapper extends BaseMapper<CodeRecord> {

    /**
     * 根据用户ID查找代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} ORDER BY created_at DESC")
    IPage<CodeRecord> findByUserIdOrderByCreatedAtDesc(Page<CodeRecord> page, @Param("userId") Long userId);
    
    /**
     * 获取用户代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} ORDER BY created_at DESC")
    IPage<CodeRecord> getUserCodeRecords(@Param("userId") Long userId, Page<CodeRecord> page);
    
    /**
     * 根据用户ID和语言获取代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} AND language = #{language} ORDER BY created_at DESC")
    IPage<CodeRecord> getUserCodeRecordsByLanguage(@Param("userId") Long userId, @Param("language") String language, Page<CodeRecord> page);
    
    /**
     * 获取用户代码记录总数
     */
    @Select("SELECT COUNT(*) FROM code_records WHERE user_id = #{userId}")
    long getUserCodeRecordCount(@Param("userId") Long userId);
    
    /**
     * 根据用户ID和语言获取代码记录总数
     */
    @Select("SELECT COUNT(*) FROM code_records WHERE user_id = #{userId} AND language = #{language}")
    long getUserCodeRecordCountByLanguage(@Param("userId") Long userId, @Param("language") String language);

    /**
     * 根据用户ID和编程语言查找代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} AND language = #{language} ORDER BY created_at DESC")
    IPage<CodeRecord> findByUserIdAndLanguageOrderByCreatedAtDesc(Page<CodeRecord> page, @Param("userId") Long userId, @Param("language") String language);

    /**
     * 根据分享令牌查找代码记录
     */
    @Select("SELECT * FROM code_records WHERE share_token = #{shareToken}")
    CodeRecord findByShareToken(@Param("shareToken") String shareToken);

    /**
     * 查找公开的代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE is_public = 1 ORDER BY created_at DESC")
    IPage<CodeRecord> findByIsPublicTrueOrderByCreatedAtDesc(Page<CodeRecord> page);

    /**
     * 根据编程语言查找公开的代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE language = #{language} AND is_public = 1 ORDER BY created_at DESC")
    IPage<CodeRecord> findByLanguageAndIsPublicTrueOrderByCreatedAtDesc(Page<CodeRecord> page, @Param("language") String language);

    /**
     * 根据用户ID统计代码记录数量
     */
    @Select("SELECT COUNT(*) FROM code_records WHERE user_id = #{userId}")
    long countByUserId(@Param("userId") Long userId);

    /**
     * 根据编程语言统计代码记录数量
     */
    @Select("SELECT COUNT(*) FROM code_records WHERE language = #{language}")
    long countByLanguage(@Param("language") String language);

    /**
     * 查找用户最近的代码记录
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} ORDER BY updated_at DESC LIMIT #{limit}")
    List<CodeRecord> findRecentByUserId(@Param("userId") Long userId, @Param("limit") int limit);

    /**
     * 根据时间范围统计执行次数
     */
    @Select("SELECT SUM(execution_count) FROM code_records WHERE created_at BETWEEN #{startTime} AND #{endTime}")
    Long countExecutionsByTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);

    /**
     * 查找热门编程语言统计
     */
    @Select("SELECT language, COUNT(*) as count FROM code_records GROUP BY language ORDER BY count DESC")
    List<Object[]> findLanguageStatistics();

    /**
     * 查找用户最常用的编程语言
     */
    @Select("SELECT language FROM code_records WHERE user_id = #{userId} GROUP BY language ORDER BY COUNT(*) DESC")
    List<String> findMostUsedLanguagesByUser(@Param("userId") Long userId);

    /**
     * 根据标题模糊查询用户的代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} AND title LIKE CONCAT('%', #{title}, '%') ORDER BY created_at DESC")
    IPage<CodeRecord> findByUserIdAndTitleContainingIgnoreCaseOrderByCreatedAtDesc(Page<CodeRecord> page, @Param("userId") Long userId, @Param("title") String title);

    /**
     * 查找用户在指定时间范围内的代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE user_id = #{userId} AND created_at BETWEEN #{startTime} AND #{endTime} ORDER BY created_at DESC")
    IPage<CodeRecord> findByUserIdAndCreatedAtBetweenOrderByCreatedAtDesc(Page<CodeRecord> page, @Param("userId") Long userId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);

    /**
     * 统计用户的总执行次数
     */
    @Select("SELECT SUM(execution_count) FROM code_records WHERE user_id = #{userId}")
    Long sumExecutionCountByUserId(@Param("userId") Long userId);

    /**
     * 统计用户的总查看次数
     */
    @Select("SELECT SUM(view_count) FROM code_records WHERE user_id = #{userId}")
    Long sumViewCountByUserId(@Param("userId") Long userId);

    /**
     * 查找最受欢迎的公开代码记录（分页）
     */
    @Select("SELECT * FROM code_records WHERE is_public = 1 ORDER BY view_count DESC, created_at DESC")
    IPage<CodeRecord> findByIsPublicTrueOrderByViewCountDescCreatedAtDesc(Page<CodeRecord> page);

    /**
     * 删除用户的所有代码记录
     */
    @Select("DELETE FROM code_records WHERE user_id = #{userId}")
    void deleteByUserId(@Param("userId") Long userId);

    /**
     * 查找需要清理的过期分享记录
     */
    @Select("SELECT * FROM code_records WHERE share_token IS NOT NULL AND shared_at < #{expireTime}")
    List<CodeRecord> findExpiredSharedRecords(@Param("expireTime") LocalDateTime expireTime);

    /**
     * 增加执行次数
     */
    @Update("UPDATE code_records SET execution_count = execution_count + 1 WHERE id = #{id}")
    void incrementExecutionCount(@Param("id") Long id);

    /**
     * 增加查看次数
     */
    @Update("UPDATE code_records SET view_count = view_count + 1 WHERE id = #{id}")
    void incrementViewCount(@Param("id") Long id);
}